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> +{{{ +}}} + +############################################################################### +